package com.dragon.refect.classload;

import java.sql.Driver;
import java.util.Iterator;
import java.util.ServiceLoader;

/**
 * 线程上下文类加载器一般使用模式(获取 - 使用 - 还原)
 *
 * ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
 * try {
 *     Thread.currentThread().setContextClassLoader(targetTccl);
 * } finally {
 *     Thread.currentThread().setContextClassLoader(classLoader);
 * }
 *
 * myMethod里面则调用了Thread.currentThread().getContextClassLoader(),获取当前线程的上下文类加载器做某些事情
 *
 * 如果一个类由类加载器A加载，那么这个类的依赖类也是由相同的类加载器加载的(如果该依赖类之前没有被加载过)
 *
 * ContextClassLoader的作用就是为了破坏Java的类加载的委托机制。
 *
 * 当高层提供了统一的接口让底层区实现，同时又要让高层加载(或实例化)底层的类时，就必须要通过线程上下文类加载器来帮助高层的classLoader
 * 找到并加载该类。
 *
 * @author dragon
 * @since 2019/11/25
 */
public class MyTest14 {

    public static void main(String[] args) {
        ServiceLoader<Driver> loader = ServiceLoader.load(Driver.class);
        for (Driver driver : loader) {
            System.out.println("driver:" + driver.getClass() + ", loader:" + driver.getClass().getClassLoader());
        }
        System.out.println("当前线程上下文类加载器:" + Thread.currentThread().getContextClassLoader());
        System.out.println("SeriveLoader的类加载器:"+ ServiceLoader.class.getClassLoader());

    }
}
